package com.lagou.position.service;

import com.lagou.position.pojo.Position;
import com.lagou.position.tools.DBHelper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class PositionService {

    private static final Logger logger = LogManager.getLogger(PositionService.class);
    private static final String POSITION_INDEX = "lagou_position";

    @Autowired
    private RestHighLevelClient client;

    public List<Position> search(String positionName, int currentPage, int pageSize)
            throws IOException, InvocationTargetException, IllegalAccessException {
        SearchResponse searchResponse = searchByPositionName(positionName, currentPage, pageSize);
        // 搜索结果
        SearchHits hits = searchResponse.getHits();
        // 匹配到的总记录数
        TotalHits totalHits = hits.getTotalHits();
        if (totalHits.value > 5) {
            return resultHandler(hits.getHits());
        } else {
            System.out.println("二次查询");
            List<Position> positions = resultHandler(hits.getHits());
            List<String> collect = positions.stream().map(Position::getId).collect(Collectors.toList());
            SearchResponse searchResponse1 = searchByPositionAdvantage(collect, 5 - positions.size());
            List<Position> positions1 = resultHandler(searchResponse1.getHits().getHits());
            List<Position> result = new ArrayList<>();
            result.addAll(positions);
            result.addAll(positions1);
            return result;
        }
    }

    private SearchResponse searchByPositionName(String positionName, int currentPage, int pageSize) throws IOException {
        // 搜索请求对象
        SearchRequest searchRequest = new SearchRequest(POSITION_INDEX);
        searchRequest.searchType(SearchType.QUERY_THEN_FETCH);
        // 搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 设置搜索方法
        searchSourceBuilder.from((currentPage - 1) * pageSize);
        searchSourceBuilder.size(pageSize);
        searchSourceBuilder.query(QueryBuilders.matchQuery("positionName", positionName));
        // 请求对象设置 搜索源对象
        searchRequest.source(searchSourceBuilder);
        System.out.println(searchRequest);
        // 使用client  执行搜索
        return client.search(searchRequest, RequestOptions.DEFAULT);
    }

    private SearchResponse searchByPositionAdvantage(List<String> notIds, int pageSize) throws IOException {
        // 搜索请求对象
        SearchRequest searchRequest = new SearchRequest(POSITION_INDEX);
        searchRequest.searchType(SearchType.QUERY_THEN_FETCH);
        // 搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 设置搜索方法
        searchSourceBuilder.query(QueryBuilders.boolQuery()
                .mustNot(QueryBuilders.termsQuery("_id", notIds))
                .must(QueryBuilders.matchQuery("positionAdvantage", "美女多 员工福利好")));
        searchSourceBuilder.size(pageSize);
        // 请求对象设置 搜索源对象
        searchRequest.source(searchSourceBuilder);
        System.out.println(searchRequest);
        // 使用client  执行搜索
        return client.search(searchRequest, RequestOptions.DEFAULT);
    }

    private List<Position> resultHandler(SearchHit[] searchHits)
            throws InvocationTargetException, IllegalAccessException {
        List<Position> result = new ArrayList<>();
        for (SearchHit hit : searchHits) {
            String id = hit.getId();
            // 源文档的内容
            Map<String, Object> sourceMap = hit.getSourceAsMap();
            Position position = new Position();
            position.setId(id);
            position.setCompanyname((String) sourceMap.get("companyName"));
            position.setPositionadvantage((String) sourceMap.get("positionAdvantage"));
            position.setCompanyid((String) sourceMap.get("companyId"));
            position.setPositionname((String) sourceMap.get("positionName"));
            position.setSalary((String) sourceMap.get("salary"));
            result.add(position);
        }
        return result;
    }

    public void importAll() throws IOException {
        writeMySQLDataToES("position");
    }

    private void writeMySQLDataToES(String tableName) {
        Connection connection = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            connection = DBHelper.getConn();
            logger.info("start handle data :" + tableName);
            String sql = "select `companyName`,`positionAdvantage`,`companyId`,`positionName`,`salary`," +
                    "`salaryMin`,`salaryMax`,`salaryMonth`,`education`,`workYear`," +
                    "`jobNature`,`chargeField`,`createTime`,`email`,`publishTime`," +
                    "`isEnable`,`isIndex`,`city`,`orderby`,`isAdvice`," +
                    "`showorder`,`publishUserId`,`workAddress`,`generateTime`,`bornTime`," +
                    "`isReward`,`rewardMoney`,`isExpired`,`positionDetailPV`,`offlineTime`," +
                    "`positionDetailPV_cnbeta`,`adviceTime`,`comeFrom`,`receivedResumeCount`,`refuseResumeCount`," +
                    "`markCanInterviewCount`,`haveNoticeInterCount`,`isForbidden`,`reason`,`verifyTime`," +
                    "`adWord`,`adRankAndTime`,`adTimes`,`adStartTime`,`adEndTime`," +
                    "`adBeforeDetailPV`,`adAfterDetailPV`,`adBeforeReceivedCount`,`adAfterReceivedCount`,`adjustScore`," +
                    "`weightStartTime`,`weightEndTime`,`isForward`,`forwardEmail`,`isSchoolJob`," +
                    "`type`,`prolong_offline_time` from " + tableName;
            ps = connection.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
            // 根据自己需要设置 fetchSize
            ps.setFetchSize(20);
            rs = ps.executeQuery();
            ResultSetMetaData colData = rs.getMetaData();
            ArrayList<HashMap<String, String>> dataList = new ArrayList<>();
            HashMap<String, String> map = null;
            // c 就是列的名字   v 就是列对应的值
            String c = null;
            String v = null;
            while (rs.next()) {
                map = new HashMap<>(128);
                for (int i = 1; i < colData.getColumnCount(); i++) {
                    c = colData.getColumnName(i);
                    v = rs.getString(c);
                    map.put(c, v);
                }
                dataList.add(map);
            }
            // 处理 未提交的数据
            for (HashMap<String, String> hashMap2 : dataList) {
                IndexRequest indexRequest = new IndexRequest();
                indexRequest.index(POSITION_INDEX);
                indexRequest.source(hashMap2);
                IndexResponse index = client.index(indexRequest, RequestOptions.DEFAULT);
                System.out.println(index);
            }
        } catch (SQLException | IOException e) {
            e.printStackTrace();
        } finally {
            try {
                rs.close();
                ps.close();
                connection.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

}
